//
//  AliMNSQueue.m
//  AlibabaCloudMNSiOS
//
//  Created by David Chen on 28/03/2017.
//  Copyright © 2017 AliCloud. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "AliMNSQueue.h"

@implementation AliMNSQueue

-(id)initWithQueueName:(NSString*) queueName
           withMNSClient:(AliMNSClient*) mnsCient
{
    mQueueName = queueName;
    mMNSClient = mnsCient;
    return self;
}

-(NSString*) create:(AliMNSQueueMeta*) queueMeta
{
    AliMNSCreateQueueRequest* cqreq = [[AliMNSCreateQueueRequest alloc] initWithQueueName: [queueMeta queueName]];
    AliMNSCreateQueueResponse* cqres = [AliMNSCreateQueueResponse new];

    // build CreateQueueRequest from queueMeta.
    [cqreq setPropertiesFromQueueMeta:queueMeta];

    // client createQueue
    [mMNSClient sendRequest: cqreq withResponse: cqres];

    //parse result from cqres.
    return cqres.queueUrl;
}

-(AliMNSQueueMeta*) getAttributes
{
    AliMNSGetQueueAttributesRequest* gqaReq = [[AliMNSGetQueueAttributesRequest alloc] initWithQueueName:mQueueName];
    AliMNSGetQueueAttributesResponse* gqaRes = [AliMNSGetQueueAttributesResponse new];

    [mMNSClient sendRequest:gqaReq withResponse:gqaRes];
    return gqaRes.queueMeta;
}

-(void) setAttributes:(AliMNSQueueMeta*) qMeta
{
    AliMNSSetQueueAttributesRequest * sqreq = [[AliMNSSetQueueAttributesRequest alloc] initWithQueueName:qMeta.queueName];
    sqreq.visibilityTimeout = qMeta.visibilityTimeout;
    sqreq.maximumMessageSize = qMeta.maximumMessageSize;
    sqreq.delaySeconds = qMeta.delaySeconds;
    sqreq.messageRetentionPeriod = qMeta.messageRetentionPeriod;

    AliMNSSetQueueAttributesResponse* sqres = [AliMNSSetQueueAttributesResponse new];

    [mMNSClient sendRequest: sqreq withResponse: sqres];
}

-(void) deleteQueue
{
    AliMNSDeleteQueueRequest* dqreq = [[AliMNSDeleteQueueRequest alloc] initWithQueueName:mQueueName];
    AliMNSDeleteQueueResponse* dqres = [AliMNSDeleteQueueResponse new];

    [mMNSClient sendRequest: dqreq withResponse: dqres];
}

-(AliMNSMessage*) sendMessage:(AliMNSMessage*) message
{
    if (message.messageBody == nil)
    {
        NSLog(@"Error:message body should not be empty!");
        return nil;
    }
    AliMNSSendMessageRequest* smReq = [[AliMNSSendMessageRequest alloc] initWithQueueName:mQueueName withMessageBody:message.messageBody];
    smReq.delaySeconds = message.delaySeconds;
    smReq.priority = message.priority;

    AliMNSSendMessageResponse* smRes = [AliMNSSendMessageResponse new];

    [mMNSClient sendRequest:smReq withResponse: smRes];

    return smRes.message;
}

-(void) asyncSendMessage:(AliMNSMessage*) message
      withSuccessHandler:(void (^)(AliMNSMessage* msg)) successHandler
         withFailHandler:(void (^)(AliMNSError* err)) failHandler
{
    if (message.messageBody == nil)
    {
        NSLog(@"Error:message body should not be empty!");
        return;
    }

    AliMNSSendMessageRequest* smReq = [[AliMNSSendMessageRequest alloc] initWithQueueName:mQueueName withMessageBody:message.messageBody];
    smReq.delaySeconds = message.delaySeconds;
    smReq.priority = message.priority;

    AliMNSSendMessageResponse* smRes = [AliMNSSendMessageResponse new];

    [mMNSClient sendAyncRequest:smReq withResponse:smRes
            withResponseHanlder: ^(AliMNSResponseBase* asyncRes)
     {
         AliMNSSendMessageResponse* inRes = (AliMNSSendMessageResponse*)asyncRes;
         AliMNSMessage* msg = inRes.message;

         if(msg != nil)
         {
             successHandler(msg);
         }else
         {
             AliMNSError* e = [inRes generateError];
             failHandler(e);
         }
     }
    ];
}

-(NSArray*) batchSendMessage:(NSArray*) messageList
{
    if (messageList == nil || messageList.count <= 0)
    {
        NSLog(@"message list is nil or empty");
        return nil;
    }

    AliMNSBatchSendMessageRequest* bsmReq = [[AliMNSBatchSendMessageRequest alloc] initWithQueueName:mQueueName withMessageList: messageList];

    AliMNSBatchSendMessageResponse* bsmRes = [AliMNSBatchSendMessageResponse new];

    [mMNSClient sendRequest:bsmReq withResponse: bsmRes];

    return bsmRes.messageList;
}

-(void) asyncBatchSendMessage:(NSArray*) messageList
           withSuccessHandler:(void (^)(NSArray* msgList)) successHandler
              withFailHandler:(void (^)(AliMNSError* err)) failHandler
{
    if (messageList == nil || messageList.count <= 0)
    {
        NSLog(@"message list is nil or empty");
        return;
    }

    AliMNSBatchSendMessageRequest* bsmReq = [[AliMNSBatchSendMessageRequest alloc] initWithQueueName:mQueueName withMessageList: messageList];
    AliMNSBatchSendMessageResponse* bsmRes = [AliMNSBatchSendMessageResponse new];

    [mMNSClient sendAyncRequest:bsmReq withResponse:bsmRes
            withResponseHanlder: ^(AliMNSResponseBase* asyncRes)
     {
         AliMNSBatchSendMessageResponse* inRes = (AliMNSBatchSendMessageResponse*)asyncRes;

         if(inRes.messageList != nil)
         {
             successHandler(inRes.messageList);
         }else
         {
             AliMNSError* e = [inRes generateError];
             failHandler(e);
         }
     }
     ];
}

-(AliMNSMessage*) peekMessage
{
    AliMNSPeekMessageRequest* peekReq = [[AliMNSPeekMessageRequest alloc] initWithQueueName:mQueueName];
    AliMNSPeekMessageResponse* peekRes = [AliMNSPeekMessageResponse new];
    [mMNSClient sendRequest:peekReq withResponse:peekRes];

    return peekRes.message;
}

-(void) asyncPeekMessageWithSuccessHandler:(void(^)(AliMNSMessage* msg)) successHandler
                      withFailHandler:(void(^)(AliMNSError* err)) failHandler
{
    AliMNSPeekMessageRequest* peekReq = [[AliMNSPeekMessageRequest alloc] initWithQueueName:mQueueName];
    AliMNSPeekMessageResponse* peekRes = [AliMNSPeekMessageResponse new];

    [mMNSClient sendAyncRequest:peekReq withResponse:peekRes
            withResponseHanlder: ^(AliMNSResponseBase* asyncRes)
     {
         AliMNSPeekMessageResponse* inRes = (AliMNSPeekMessageResponse*)asyncRes;

         if(inRes.message != nil)
         {
             successHandler(inRes.message);
         }else
         {
             AliMNSError* e = [inRes generateError];
             failHandler(e);
         }
     }
     ];
}

-(NSArray*) batchPeekMessage:(NSInteger) batchSize
{
    AliMNSBatchPeekMessageRequest* bpReq = [[AliMNSBatchPeekMessageRequest alloc]initWithQueueName:mQueueName withNumOfMessages:batchSize];

    bpReq.numOfMessages = batchSize;
    AliMNSBatchPeekMessageResponse* bpRes = [AliMNSBatchPeekMessageResponse new];

    [mMNSClient sendRequest:bpReq withResponse:bpRes];
    return bpRes.messageList;
}

-(void) asyncBatchPeekMessage:(NSInteger) batchSize
      withSuccessHandler:(void(^)(NSArray* msgList)) successHandler
         withFailHandler:(void(^)(AliMNSError* err)) failHandler
{
    AliMNSBatchPeekMessageRequest* bpReq = [[AliMNSBatchPeekMessageRequest alloc]initWithQueueName:mQueueName withNumOfMessages:batchSize];

    bpReq.numOfMessages = batchSize;
    AliMNSBatchPeekMessageResponse* bpRes = [AliMNSBatchPeekMessageResponse new];

    [mMNSClient sendAyncRequest:bpReq withResponse:bpRes
            withResponseHanlder: ^(AliMNSResponseBase* asyncRes)
     {
         AliMNSBatchPeekMessageResponse* inRes = (AliMNSBatchPeekMessageResponse*)asyncRes;

         if(inRes.messageList != nil)
         {
             successHandler(inRes.messageList);
         }else
         {
             AliMNSError* e = [inRes generateError];
             failHandler(e);
         }
     }
     ];
}


-(AliMNSMessage*) receiveMessage:(NSInteger)waitSeconds
{
    AliMNSReceiveMessageRequest* receiveReq = [[AliMNSReceiveMessageRequest alloc] initWithQueueName:mQueueName];

    receiveReq.waitSeconds = waitSeconds;
    AliMNSReceiveMessageResponse* receiveRes = [AliMNSReceiveMessageResponse new];

    [mMNSClient sendRequest:receiveReq withResponse:receiveRes];
    return receiveRes.message;
}

-(void) asyncReceiveMessage:(NSInteger)waitSeconds
         withSuccessHandler:(void(^)(AliMNSMessage* msg)) successHandler
            withFailHandler:(void(^)(AliMNSError* err)) failHandler
{
    AliMNSReceiveMessageRequest* receiveReq = [[AliMNSReceiveMessageRequest alloc] initWithQueueName:mQueueName];
    receiveReq.waitSeconds = waitSeconds;

    AliMNSReceiveMessageResponse* receiveRes = [AliMNSReceiveMessageResponse new];

    [mMNSClient sendAyncRequest:receiveReq withResponse:receiveRes
            withResponseHanlder: ^(AliMNSResponseBase* asyncRes)
     {
         AliMNSReceiveMessageResponse* inRes = (AliMNSReceiveMessageResponse*)asyncRes;

         if(inRes.message != nil)
         {
             successHandler(inRes.message);
         }else
         {
             AliMNSError* e = [inRes generateError];
             failHandler(e);
         }
     }
     ];
}

-(NSArray*) batchReceiveMessage:(NSInteger)waitSeconds
                  withBatchSize:(NSInteger) batchSize
{
    AliMNSBatchReceiveMessageRequest* brmReq = [[AliMNSBatchReceiveMessageRequest alloc] initWithQueueName:mQueueName withNumOfMessages:batchSize];

    brmReq.waitSeconds = waitSeconds;
    brmReq.numOfMessages = batchSize;

    AliMNSBatchReceiveMessageResponse* brmRes = [AliMNSBatchReceiveMessageResponse new];

    [mMNSClient sendRequest:brmReq withResponse: brmRes];

    return brmRes.messageList;
}

-(void) asyncBatchReceiveMessage:(NSInteger)waitSeconds
              withBatchSize:(NSInteger) batchSize
         withSuccessHandler:(void(^)(NSArray* msg)) successHandler
            withFailHandler:(void(^)(AliMNSError* err)) failHandler
{
    AliMNSBatchReceiveMessageRequest* brmReq = [[AliMNSBatchReceiveMessageRequest alloc] initWithQueueName:mQueueName withNumOfMessages:batchSize];
    brmReq.waitSeconds = waitSeconds;
     brmReq.numOfMessages = batchSize;
    AliMNSBatchReceiveMessageResponse* brmRes = [AliMNSBatchReceiveMessageResponse new];

    [mMNSClient sendAyncRequest:brmReq withResponse:brmRes
            withResponseHanlder: ^(AliMNSResponseBase* asyncRes){
        AliMNSBatchReceiveMessageResponse* inRes = (AliMNSBatchReceiveMessageResponse*)asyncRes;

        if(inRes.messageList != nil)
        {
            successHandler(inRes.messageList);
        }else
        {
            AliMNSError* e = [inRes generateError];
            failHandler(e);
        }
    }];
}

-(void) deleteMessage:(NSString*)receiptHandle
{
    if(receiptHandle == nil || [receiptHandle isEqualToString:@""])
    {
        NSLog(@"receiptHandle should not be empty.");
        return;
    }

    AliMNSDeleteMessageRequest* dmReq = [[AliMNSDeleteMessageRequest alloc] initWithQueueName:mQueueName withReceiptHandle:receiptHandle];
    AliMNSDeleteMessageResponse* dmRes = [AliMNSDeleteMessageResponse new];

    [mMNSClient sendRequest:dmReq withResponse:dmRes];
}

-(void) asyncDeleteMessage:(NSString*)receiptHandle
        withSuccessHandler:(void(^)()) successHandler
           withFailHandler:(void(^)(AliMNSError* err)) failHandler
{
    if(receiptHandle == nil || [receiptHandle isEqualToString:@""])
    {
        NSLog(@"receiptHandle should not be empty.");
        return;
    }

    AliMNSDeleteMessageRequest* dmReq = [[AliMNSDeleteMessageRequest alloc] initWithQueueName:mQueueName withReceiptHandle:receiptHandle];
    AliMNSDeleteMessageResponse* dmRes = [AliMNSDeleteMessageResponse new];
    [mMNSClient sendAyncRequest:dmReq withResponse:dmRes
            withResponseHanlder: ^(AliMNSResponseBase* asyncRes){
                AliMNSDeleteMessageResponse* inRes = (AliMNSDeleteMessageResponse*)asyncRes;
                AliMNSError* e = [inRes generateError];
                if(e == nil)
                {
                    successHandler();
                }else
                {
                    failHandler(e);
                }
            }];
}


-(void) batchDeleteMessage:(NSArray*)receiptHanleList
{
    if(receiptHanleList == nil || receiptHanleList.count == 0)
    {
        NSLog(@"receiptHandle should not be empty.");
        return;
    }
    AliMNSBatchDeleteMessageRequest* bdmReq = [[AliMNSBatchDeleteMessageRequest alloc] initWithQueueName:mQueueName withReceiptHandleList:receiptHanleList];
    AliMNSBatchDeleteMessageResponse* bdmRes = [AliMNSBatchDeleteMessageResponse new];
    [mMNSClient sendRequest:bdmReq withResponse:bdmRes];
}

-(void) asyncBatchDeleteMessage:(NSArray*)receiptHanleList
             withSuccessHandler:(void(^)()) successHandler
                withFailHandler:(void(^)(AliMNSError* err)) failHandler
{
    if(receiptHanleList == nil || receiptHanleList.count == 0)
    {
        NSLog(@"receiptHandle should not be empty.");
        return;
    }
    AliMNSBatchDeleteMessageRequest* bdmReq = [[AliMNSBatchDeleteMessageRequest alloc] initWithQueueName:mQueueName withReceiptHandleList:receiptHanleList];
    AliMNSBatchDeleteMessageResponse* bdmRes = [AliMNSBatchDeleteMessageResponse new];

    [mMNSClient sendAyncRequest:bdmReq withResponse:bdmRes
            withResponseHanlder: ^(AliMNSResponseBase* asyncRes){
                AliMNSBatchDeleteMessageResponse* inRes = (AliMNSBatchDeleteMessageResponse*)asyncRes;
                AliMNSError* e = [inRes generateError];
                if(e == nil)
                {
                    successHandler();
                }else
                {
                    failHandler(e);
                }
            }];
}

-(AliMNSMessage*) changeMessageVisibility:(NSString*)receiptHandle
                    withVisibilityTimeout:(NSInteger) visibilityTimeout
{
    AliMNSChangeMessageVisibilityRequest* chReq = [[AliMNSChangeMessageVisibilityRequest alloc] initWithQueueName:mQueueName withReceiptHandle:receiptHandle withVisibilityTimeout:visibilityTimeout];
    AliMNSChangeMessageVisibilityResponse* chRes = [AliMNSChangeMessageVisibilityResponse new];
    [mMNSClient sendRequest:chReq withResponse:chRes];

    AliMNSMessage* msg = [AliMNSMessage new];
    msg.receiptHandle = chRes.receiptHandle;
    msg.nextVisibleTime = chRes.nextVisibleTime;
    return msg;
}
@end
